package com.cskaoyan.market.service;

import com.cskaoyan.market.db.domain.*;
import com.cskaoyan.market.db.mapper.*;
import com.cskaoyan.market.util.MybatisUtils;
import com.cskaoyan.market.vo.CatAndBrandVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AdminGoodsServiceImpl implements AdminGoodsService{
    @Override
    public List<MarketGoods> list(String page, String limit, String sort, String order, String goodsSn, String name, String goodsId) {
        SqlSession session= MybatisUtils.getSession();
        MarketGoodsMapper MarketGoodsMapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        if (!StringUtils.isEmpty(goodsSn)){
            criteria.andGoodsSnEqualTo(goodsSn);
        }
        if (!StringUtils.isEmpty(name)){
            criteria.andNameLike("%"+name+"%");
        }
        if (!StringUtils.isEmpty(goodsId)){
            criteria.andIdEqualTo(Integer.valueOf(goodsId));
        }
        List<MarketGoods> goodsList=MarketGoodsMapper.selectByExample(marketGoodsExample);
        session.close();
        return goodsList;
    }
    public Map<String, Object> catAndBrand() {
        //展示出品牌和分类信息
        //需要到数据库中执行两次查询操作
        SqlSession session = MybatisUtils.getSession();
        MarketBrandMapper brandMapper = session.getMapper(MarketBrandMapper.class);
        MarketCategoryMapper categoryMapper = session.getMapper(MarketCategoryMapper.class);
        //如果使用物理删除，那么deleted属性就可以直接忽略不用去理会了，直接删除该条记录即可
        //deleted=0表示的是没有删除；=1表示的是删除----可以是逻辑删除
        List<MarketBrand> brands = brandMapper.selectByExample(new MarketBrandExample());
        List<MarketCategory> categories = categoryMapper.selectByExample(new MarketCategoryExample());
        session.close();


        //把brand的实体对象转换成vo，放入一个list中
        List<CatAndBrandVo> brandVos = new ArrayList<>();
        for (MarketBrand brand : brands) {
            brandVos.add(new CatAndBrandVo(brand.getId(), brand.getName(), null));
        }

        List<CatAndBrandVo> categoriesVos = new ArrayList<>();

        Map<Integer, List<MarketCategory>> result = groupByPid(categories);
        List<MarketCategory> l1Categories = result.get(0);
        for (MarketCategory l1Category : l1Categories) {
            //转换成vo，放入list中
            List<CatAndBrandVo> children = new ArrayList<>();
            categoriesVos.add(new CatAndBrandVo(l1Category.getId(), l1Category.getName(), children));
            Integer id = l1Category.getId();
            List<MarketCategory> l2CategoriesOfl1 = result.get(id);
            for (MarketCategory l2 : l2CategoriesOfl1) {
                children.add(new CatAndBrandVo(l2.getId(), l2.getName(), null));
            }
        }


        //最后把需要的这两部分数据返回即可
        Map<String, Object> map = new HashMap<>();
        map.put("brandList", brandVos);
        map.put("categoryList", categoriesVos);
        return map;
    }

    @Override
    public void insert(MarketGoods goods, List<MarketGoodsSpecification> specifications, List<MarketGoodsAttribute> attributes, List<MarketGoodsProduct> products) {
        //首先给goods赋值，还有一些属性没有值，retailPrice  时间  deleted(如果是物理删除，那么不用理会该字段)
        //应该获取位于products里面较低的价格，赋值给retailPrice
        BigDecimal retailPrice = products.get(0).getPrice();
        for (int i = 0; i < products.size(); i++) {
            MarketGoodsProduct product = products.get(i);
            //遍历，如果出现了一个更小的价格，那么把更小的价格赋值给retailPrice
            // -1 小于 0 等于 1  大于
            if(product.getPrice().compareTo(retailPrice) == -1){
                retailPrice = product.getPrice();
            }
        }

        goods.setRetailPrice(retailPrice);
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goods.setDeleted(false);
        SqlSession session = MybatisUtils.getSession();
        MarketGoodsMapper marketGoodsMapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsSpecificationMapper specificationMapper = session.getMapper(MarketGoodsSpecificationMapper.class);
        MarketGoodsProductMapper productMapper = session.getMapper(MarketGoodsProductMapper.class);
        MarketGoodsAttributeMapper attributeMapper = session.getMapper(MarketGoodsAttributeMapper.class);
        // insert into (xx,xx) values (xx,xx)---除了这两列之外的其他列，如果有默认值，则会赋值默认值
        // insert into xxx values (xx,xx,xx,xx,xx,xx)---给全部的列赋值，但是实体类里面有很多的null，所以这一列会被赋值null
        try {
            marketGoodsMapper.insert(goods);
            Integer goodsId = goods.getId();
            //关于下面这三个插入，大家可以自定义一个插入方法，使用foreach标签来进行
            for (MarketGoodsSpecification sp : specifications) {
                sp.setGoodsId(goodsId);
                sp.setAddTime(LocalDateTime.now());
                sp.setUpdateTime(LocalDateTime.now());
                specificationMapper.insert(sp);
            }
            for (MarketGoodsAttribute attribute : attributes) {
                attribute.setGoodsId(goodsId);
                attribute.setAddTime(LocalDateTime.now());
                attribute.setUpdateTime(LocalDateTime.now());
                attributeMapper.insert(attribute);
            }

            for (MarketGoodsProduct product : products) {
                product.setAddTime(LocalDateTime.now());
                product.setUpdateTime(LocalDateTime.now());
                product.setGoodsId(goodsId);
                productMapper.insert(product);
            }
            session.commit();
        }catch (Exception e){
            session.rollback();
            e.printStackTrace();
        }finally {
            session.close();
        }
    }

    //按照pid进行分组
    private Map<Integer, List<MarketCategory>> groupByPid(List<MarketCategory> categories) {
        Map<Integer, List<MarketCategory>> result = new HashMap<>();
        for (MarketCategory category : categories) {
            //尝试从map中根据pid的值去获取数据
            Integer pid = category.getPid();
            List<MarketCategory> list = result.get(pid);
            if(list == null){
                list = new ArrayList<>();
            }
            list.add(category);
            result.put(pid, list);
        }
        return result;
    }


}
